<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */

namespace Haozing\FastCore\Annotation\OpenDoc;

use Hyperf\Contract\Arrayable;
use Hyperf\Di\Annotation\AnnotationCollector;
use Hyperf\Di\Annotation\AnnotationInterface;
use Hyperf\Di\ReflectionManager;
use ReflectionProperty;

abstract class AbstractAnnotation implements AnnotationInterface, Arrayable
{
    //存放数据的字段
    public array $array = [];
    public function toArray(): array
    {
        $properties = ReflectionManager::reflectClass(static::class)->getProperties(ReflectionProperty::IS_PUBLIC);
        $result = [];
        foreach ($properties as $property) {
            $result[$property->getName()] = $property->getValue($this);
        }
        return $result;
    }

    public function collectClass(string $className): void
    {
        //先查原先的数据，然后合并数据，然后再存回去
        $data = AnnotationCollector::getClassAnnotation($className, static::class);
        if ($data) {
            $data->setArray($this->toArray());
        }else{
            $this->setArray($this->toArray());
            $data = $this;
        }

        AnnotationCollector::collectClass($className, static::class,$data);
    }

    public function collectClassConstant(string $className, ?string $target): void
    {
        $constants = AnnotationCollector::getClassConstantAnnotation($className, $target);
        //从$constants中取出static::class的数据
        $data = $constants[static::class] ?? [];
        if ($data) {
            $data->setArray($this->toArray());
        }else{
            $this->setArray($this->toArray());
            $data = $this;
        }
        AnnotationCollector::collectClassConstant($className, $target, static::class, $data);
    }

    public function collectMethod(string $className, ?string $target): void
    {
        $class = AnnotationCollector::getClassMethodAnnotation($className, $target);
        $data = $class[static::class] ?? [];

        if ($data) {
            $data->setArray($this->toArray());
        }else{
            $this->setArray($this->toArray());
            $data = $this;
        }
        AnnotationCollector::collectMethod($className, $target, static::class, $data);
    }

    public function collectProperty(string $className, ?string $target): void
    {
        $property = AnnotationCollector::getClassPropertyAnnotation($className, $target);
        $data = $property[static::class] ?? [];
        if ($data) {
            $data->setArray($this->toArray());
        }else{
            $this->setArray($this->toArray());
            $data = $this;
        }
        AnnotationCollector::collectProperty($className, $target, static::class, $data);
    }

    /**
     * 给array数组进行赋值
     */
    public function setArray($value): void
    {
        $this->array[] = $value;
    }
    public function getArray(): array
    {
        return $this->array;
    }
}
